﻿var Ajax = window.Ajax || {
	request: function (ops, callback, fail) {
		if (typeof ops == 'string') {
			ops = {
				url: ops
			};
			if (typeof callback == 'function') {
				ops.done = callback;
			}
			if (typeof fail == 'function') {
				ops.fail = fail;
			}
		}
		ops.url = ops.url || '';
		ops.type = ops.type || 'get';
		ops.data = ops.data || {};
		ops.nocache = ops.nocache || false;
		ops.progress = ops.progress || function () { };
		ops.done = ops.done || function () { };
		ops.fail = ops.fail || function () { };
		ops.always = ops.always || function () { };
		if (ops.nocache) {
			var parametr = '';
			while (parametr.length < 5) {
				parametr += String.fromCharCode(97 + Math.floor(Math.random() * (100))).replace(/\W/g, '');
			}
			ops.data[parametr] = new Date().getTime();
		}
		var getParams = function (data, url) {
			var arr = [],
				str;
			for (var name in data) {
				arr.push(name + '=' + encodeURIComponent(data[name]));
			}
			str = arr.join('&');
			if (str != '') {
				return url ? (url.indexOf('?') < 0 ? '?' + str : '&' + str) : str;
			}
			return '';
		};
		var setHeaders = function (headers) {
			for (var name in headers) {
				this.xhr && this.xhr.setRequestHeader(name, headers[name]);
			}
		};
		var api = {
			host: {},
			process: function (ops) {
				var self = this;
				this.xhr = null;
				if (window.ActiveXObject) {
					this.xhr = new ActiveXObject('Microsoft.XMLHTTP');
				} else if (window.XMLHttpRequest) {
					this.xhr = new XMLHttpRequest();
				}
				if (this.xhr) {
					this.xhr.onreadystatechange = function () {
						if (self.xhr.readyState == 4 && self.xhr.status == 200) {
							var result = self.xhr.responseText;
							if (ops.json === true && typeof JSON != 'undefined') {
								result = JSON.parse(result);
							}
							ops.done && ops.done.apply(self.host, [result, self.xhr]);
							ops.always && ops.always.apply(self.host, [self.xhr]);
						} else if (self.xhr.readyState == 4) {
							ops.fail && ops.fail.apply(self.host, [self.xhr]);
							ops.always && ops.always.apply(self.host, [self.xhr]);
						}
					};
					this.xhr.onprogress = ops.progress;
				}
				if (ops.type.toLocaleLowerCase() == 'get') {
					this.xhr.open('GET', ops.url + getParams(ops.data, ops.url), true);
				} else {
					this.xhr.open(ops.type.toLocaleUpperCase(), ops.url, true);
					setHeaders({
						'X-Requested-With': 'XMLHttpRequest',
						'Content-type': 'application/x-www-form-urlencoded'
					});
				}
				if (ops.headers && typeof ops.headers == 'object') {
					setHeaders(ops.headers);
				}
				ops.type.toLocaleLowerCase() == 'get' ? self.xhr.send() : self.xhr.send(getParams(ops.data));
			}
		};
		api.process(ops);
	},
	getScript: function (url, callback, fail) {
		Ajax.request({
			url: url,
			done: function (result, xhr) {
				var script = document.createElement('script');
				script.text = result;
				document.getElementsByTagName('head')[0].appendChild(script).parentNode.removeChild(script);
				callback && callback(result, xhr);
			},
			fail: fail
		});
	},
	getScripts: function (urls, callback, fail) {
		var count = urls.length,
			n = 0,
			hasError = false;
		for (var i = 0; i < count; i++) {
			Ajax.getScript(urls[i], callbackLocal, localFail);
		}

		function callbackLocal(result, xhr) {
			n++;
			if (n < count) return;
			if (hasError) {
				fail && fail(xhr);
				return;
			}
			callback && callback(xhr);
		}

		function localFail() {
			hasError = true;
		}
	},
	get: function (ops, callback, fail) {
		ops.type = 'get';
		Ajax.request(ops, callback, fail);
	},
	post: function (ops, callback, fail) {
		ops.type = 'post';
		Ajax.request(ops, callback, fail);
	},
	getJSON: function (url, callback, fail) {
		Ajax.get(url, function (response, xhr) {
			callback && callback(JSON.parse(response), xhr);
		}, fail);
	}
};